diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 03d0890408..5d36718e9a 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -47,7 +47,7 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [ dataFetcher("/api/enterprises/accessible?template=bulk_index&q[sells_in][]=own&q[sells_in][]=any").then (data) -> $scope.distributors = data $scope.distributors.unshift blankOption() - ocFetcher = dataFetcher("/api/order_cycles/accessible").then (data) -> + ocFetcher = dataFetcher("/api/order_cycles/accessible?as=distributor&q[orders_close_at_gt]=#{formatDate(daysFromToday(-90))}").then (data) -> $scope.orderCycles = data $scope.orderCycles.unshift blankOption() $scope.fetchOrders() diff --git a/app/controllers/api/order_cycles_controller.rb b/app/controllers/api/order_cycles_controller.rb index b4b3486778..23b333625e 100644 --- a/app/controllers/api/order_cycles_controller.rb +++ b/app/controllers/api/order_cycles_controller.rb @@ -9,7 +9,16 @@ module Api end def accessible - @order_cycles = OrderCycle.ransack(params[:q]).result.accessible_by(current_api_user) + @order_cycles = if params[:as] == "distributor" + OrderCycle.ransack(params[:q]).result. + involving_managed_distributors_of(current_api_user).order('updated_at DESC') + elsif params[:as] == "producer" + OrderCycle.ransack(params[:q]).result. + involving_managed_producers_of(current_api_user).order('updated_at DESC') + else + OrderCycle.ransack(params[:q]).result.accessible_by(current_api_user) + end + render params[:template] || :bulk_index end end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index adcd596a8c..d16f1d7b8b 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -26,7 +26,7 @@ class OrderCycle < ActiveRecord::Base closed. where("order_cycles.orders_close_at >= ?", 31.days.ago). order("order_cycles.orders_close_at DESC") } - + scope :soonest_opening, lambda { upcoming.order('order_cycles.orders_open_at ASC') } scope :distributing_product, lambda { |product| @@ -64,6 +64,23 @@ class OrderCycle < ActiveRecord::Base joins('LEFT OUTER JOIN enterprises ON (enterprises.id = exchanges.sender_id OR enterprises.id = exchanges.receiver_id)') } + scope :involving_managed_distributors_of, lambda { |user| + enterprises = Enterprise.managed_by(user) + + # Order cycles where I managed an enterprise at either end of an outgoing exchange + # ie. coordinator or distibutor + joins(:exchanges).merge(Exchange.outgoing). + where('exchanges.receiver_id IN (?) OR exchanges.sender_id IN (?)', enterprises, enterprises) + } + + scope :involving_managed_producers_of, lambda { |user| + enterprises = Enterprise.managed_by(user) + + # Order cycles where I managed an enterprise at either end of an incoming exchange + # ie. coordinator or producer + joins(:exchanges).merge(Exchange.incoming). + where('exchanges.receiver_id IN (?) OR exchanges.sender_id IN (?)', enterprises, enterprises) + } def self.first_opening_for(distributor) with_distributor(distributor).soonest_opening.first diff --git a/spec/controllers/api/order_cycles_controller_spec.rb b/spec/controllers/api/order_cycles_controller_spec.rb index a9cceac796..3bb9a76602 100644 --- a/spec/controllers/api/order_cycles_controller_spec.rb +++ b/spec/controllers/api/order_cycles_controller_spec.rb @@ -4,109 +4,210 @@ require 'spree/api/testing_support/helpers' module Api describe OrderCyclesController do include Spree::Api::TestingSupport::Helpers + include AuthenticationWorkflow render_views - let!(:oc1) { FactoryGirl.create(:simple_order_cycle) } - let!(:oc2) { FactoryGirl.create(:simple_order_cycle) } - let(:coordinator) { oc1.coordinator } - let(:attributes) { [:id, :name, :suppliers, :distributors] } + describe "managed" do + let!(:oc1) { FactoryGirl.create(:simple_order_cycle) } + let!(:oc2) { FactoryGirl.create(:simple_order_cycle) } + let(:coordinator) { oc1.coordinator } + let(:attributes) { [:id, :name, :suppliers, :distributors] } - before do - stub_authentication! - Spree.user_class.stub :find_by_spree_api_key => current_api_user - end + before do + stub_authentication! + Spree.user_class.stub :find_by_spree_api_key => current_api_user + end - context "as a normal user" do - sign_in_as_user! + context "as a normal user" do + sign_in_as_user! - it "should deny me access to managed order cycles" do - spree_get :managed, { :format => :json } - assert_unauthorized! + it "should deny me access to managed order cycles" do + spree_get :managed, { :format => :json } + assert_unauthorized! + end + end + + context "as an enterprise user" do + sign_in_as_enterprise_user! [:coordinator] + + it "retrieves a list of variants with appropriate attributes" do + get :managed, { :format => :json } + keys = json_response.first.keys.map{ |key| key.to_sym } + attributes.all?{ |attr| keys.include? attr }.should == true + end + end + + context "as an administrator" do + sign_in_as_admin! + + it "retrieves a list of variants with appropriate attributes" do + get :managed, { :format => :json } + keys = json_response.first.keys.map{ |key| key.to_sym } + attributes.all?{ |attr| keys.include? attr }.should == true + end end end - context "as an enterprise user" do - sign_in_as_enterprise_user! [:coordinator] + describe "accessible" do + context "without :as parameter" do + let(:oc_supplier) { create(:supplier_enterprise) } + let(:oc_distributor) { create(:distributor_enterprise) } + let(:other_supplier) { create(:supplier_enterprise) } + let(:oc_supplier_user) do + user = create(:user) + user.spree_roles = [] + user.enterprise_roles.create(enterprise: oc_supplier) + user.save! + user + end + let(:oc_distributor_user) do + user = create(:user) + user.spree_roles = [] + user.enterprise_roles.create(enterprise: oc_distributor) + user.save! + user + end + let(:other_supplier_user) do + user = create(:user) + user.spree_roles = [] + user.enterprise_roles.create(enterprise: other_supplier) + user.save! + user + end + let!(:order_cycle) { create(:simple_order_cycle, suppliers: [oc_supplier], distributors: [oc_distributor]) } - it "retrieves a list of variants with appropriate attributes" do - get :managed, { :format => :json } - keys = json_response.first.keys.map{ |key| key.to_sym } - attributes.all?{ |attr| keys.include? attr }.should == true - end - end + context "as the user of a supplier to an order cycle" do + before :each do + stub_authentication! + Spree.user_class.stub :find_by_spree_api_key => oc_supplier_user + spree_get :accessible, { :template => 'bulk_index', :format => :json } + end - context "as an administrator" do - sign_in_as_admin! + it "gives me access" do + json_response.length.should == 1 + json_response[0]['id'].should == order_cycle.id + end + end - it "retrieves a list of variants with appropriate attributes" do - get :managed, { :format => :json } - keys = json_response.first.keys.map{ |key| key.to_sym } - attributes.all?{ |attr| keys.include? attr }.should == true - end - end + context "as the user of some other supplier" do + before :each do + stub_authentication! + Spree.user_class.stub :find_by_spree_api_key => other_supplier_user + spree_get :accessible, { :template => 'bulk_index', :format => :json } + end - context "using the accessible action to list order cycles" do - let(:oc_supplier) { create(:supplier_enterprise) } - let(:oc_distributor) { create(:distributor_enterprise) } - let(:other_supplier) { create(:supplier_enterprise) } - let(:oc_supplier_user) do - user = create(:user) - user.spree_roles = [] - user.enterprise_roles.create(enterprise: oc_supplier) - user.save! - user - end - let(:oc_distributor_user) do - user = create(:user) - user.spree_roles = [] - user.enterprise_roles.create(enterprise: oc_distributor) - user.save! - user - end - let(:other_supplier_user) do - user = create(:user) - user.spree_roles = [] - user.enterprise_roles.create(enterprise: other_supplier) - user.save! - user - end - let!(:order_cycle) { create(:simple_order_cycle, suppliers: [oc_supplier], distributors: [oc_distributor]) } + it "does not give me access" do + json_response.length.should == 0 + end + end - context "as the user of a supplier to an order cycle" do - before :each do + context "as the user of a hub for the order cycle" do + before :each do + stub_authentication! + Spree.user_class.stub :find_by_spree_api_key => oc_distributor_user + spree_get :accessible, { :template => 'bulk_index', :format => :json } + end + + it "gives me access" do + json_response.length.should == 1 + json_response[0]['id'].should == order_cycle.id + end + end + end + + context "when the :as parameter is set to 'distributor'" do + let(:user) { create_enterprise_user } + let(:distributor) { create(:distributor_enterprise) } + let(:producer) { create(:supplier_enterprise) } + let(:coordinator) { create(:distributor_enterprise) } + let!(:oc) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor], suppliers: [producer]) } + + let(:params) { { format: :json, as: 'distributor' } } + + before do stub_authentication! - Spree.user_class.stub :find_by_spree_api_key => oc_supplier_user - spree_get :accessible, { :template => 'bulk_index', :format => :json } + Spree.user_class.stub :find_by_spree_api_key => user end - it "gives me access" do - json_response.length.should == 1 - json_response[0]['id'].should == order_cycle.id + context "as the manager of a supplier in an order cycle" do + before do + user.enterprise_roles.create(enterprise: producer) + spree_get :accessible, params + end + + it "does not return the order cycle" do + expect(assigns(:order_cycles)).to_not include oc + end + end + + context "as the manager of a distributor in an order cycle" do + before do + user.enterprise_roles.create(enterprise: distributor) + spree_get :accessible, params + end + + it "returns the order cycle" do + expect(assigns(:order_cycles)).to include oc + end + end + + context "as the manager of the coordinator of an order cycle" do + before do + user.enterprise_roles.create(enterprise: coordinator) + spree_get :accessible, params + end + + it "returns the order cycle" do + expect(assigns(:order_cycles)).to include oc + end end end - context "as the user of some other supplier" do - before :each do + context "when the :as parameter is set to 'producer'" do + let(:user) { create_enterprise_user } + let(:distributor) { create(:distributor_enterprise) } + let(:producer) { create(:supplier_enterprise) } + let(:coordinator) { create(:distributor_enterprise) } + let!(:oc) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor], suppliers: [producer]) } + + let(:params) { { format: :json, as: 'producer' } } + + before do stub_authentication! - Spree.user_class.stub :find_by_spree_api_key => other_supplier_user - spree_get :accessible, { :template => 'bulk_index', :format => :json } + Spree.user_class.stub :find_by_spree_api_key => user end - it "does not give me access" do - json_response.length.should == 0 - end - end + context "as the manager of a producer in an order cycle" do + before do + user.enterprise_roles.create(enterprise: producer) + spree_get :accessible, params + end - context "as the user of a hub for the order cycle" do - before :each do - stub_authentication! - Spree.user_class.stub :find_by_spree_api_key => oc_distributor_user - spree_get :accessible, { :template => 'bulk_index', :format => :json } + it "returns the order cycle" do + expect(assigns(:order_cycles)).to include oc + end end - it "gives me access" do - json_response.length.should == 1 - json_response[0]['id'].should == order_cycle.id + context "as the manager of a distributor in an order cycle" do + before do + user.enterprise_roles.create(enterprise: distributor) + spree_get :accessible, params + end + + it "does not return the order cycle" do + expect(assigns(:order_cycles)).to_not include oc + end + end + + context "as the manager of the coordinator of an order cycle" do + before do + user.enterprise_roles.create(enterprise: coordinator) + spree_get :accessible, params + end + + it "returns the order cycle" do + expect(assigns(:order_cycles)).to include oc + end end end end diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index 61164870ed..e92f65ed5b 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -23,7 +23,7 @@ describe "AdminOrderMgmtCtrl", -> httpBackend.expectGET("/api/users/authorise_api?token=API_KEY").respond success: "Use of API Authorised" httpBackend.expectGET("/api/enterprises/accessible?template=bulk_index&q[is_primary_producer_eq]=true").respond returnedSuppliers httpBackend.expectGET("/api/enterprises/accessible?template=bulk_index&q[sells_in][]=own&q[sells_in][]=any").respond returnedDistributors - httpBackend.expectGET("/api/order_cycles/accessible").respond returnedOrderCycles + httpBackend.expectGET("/api/order_cycles/accessible?as=distributor&q[orders_close_at_gt]=SomeDate").respond returnedOrderCycles spyOn(scope, "initialiseVariables").andCallThrough() spyOn(scope, "fetchOrders").andReturn "nothing" #spyOn(returnedSuppliers, "unshift")