diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 651785e999..924510dbfc 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -61,6 +61,10 @@ module Admin end end + protected + def collection + OrderCycle.managed_by(spree_current_user) + end private def load_order_cycle_set diff --git a/app/helpers/order_cycles_helper.rb b/app/helpers/order_cycles_helper.rb index cc85b9e69b..ab202cc50c 100644 --- a/app/helpers/order_cycles_helper.rb +++ b/app/helpers/order_cycles_helper.rb @@ -4,7 +4,7 @@ module OrderCyclesHelper end def coordinating_enterprises - Enterprise.is_distributor.order('name') + Enterprise.is_distributor.managed_by(spree_current_user).order('name') end def order_cycle_local_remote_class(distributor, order_cycle) diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index a6bc72ffe1..51af905060 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -20,6 +20,14 @@ class OrderCycle < ActiveRecord::Base where('spree_variants.id IN (?)', product.variants_including_master.map(&:id)). select('DISTINCT order_cycles.*') } + scope :managed_by, lambda { |user| + if user.has_spree_role?('admin') + scoped + else + where('coordinator_id IN (?)', user.enterprises.map {|enterprise| enterprise.id }) + end + } + def suppliers self.exchanges.where(:receiver_id => self.coordinator).map(&:sender).uniq end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 67837feaea..f29b8046c7 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -23,7 +23,7 @@ class AbilityDecorator user.enterprises.include? order.distributor end - can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment + can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization @@ -33,6 +33,13 @@ class AbilityDecorator can [:admin, :read, :update, :fire, :resend ], Spree::PaymentMethod do |payment_method| user.enterprises.include? payment_method.distributor end + + can [:admin, :index, :read, :edit, :update], OrderCycle do |order_cycle| + user.enterprises.include? order_cycle.coordinator + end + + can [:create], OrderCycle + end end end diff --git a/app/views/admin/order_cycles/_form.html.haml b/app/views/admin/order_cycles/_form.html.haml index 132d082049..0f1cac71fc 100644 --- a/app/views/admin/order_cycles/_form.html.haml +++ b/app/views/admin/order_cycles/_form.html.haml @@ -25,7 +25,7 @@ %tr.products{'ng-show' => 'exchange.showProducts'} = render 'exchange_supplied_products_form' -= select_tag :new_supplier_id, options_from_collection_for_select(Enterprise.is_primary_producer, :id, :name), {'ng-model' => 'new_supplier_id'} += select_tag :new_supplier_id, options_from_collection_for_select(Enterprise.is_primary_producer.managed_by(spree_current_user), :id, :name), {'ng-model' => 'new_supplier_id'} = f.submit 'Add supplier', 'ng-click' => 'addSupplier($event)' @@ -50,7 +50,7 @@ %tr.products{'ng-show' => 'exchange.showProducts'} = render 'exchange_distributed_products_form' -= select_tag :new_distributor_id, options_from_collection_for_select(Enterprise.is_distributor, :id, :name), {'ng-model' => 'new_distributor_id'} += select_tag :new_distributor_id, options_from_collection_for_select(Enterprise.is_distributor.managed_by(spree_current_user), :id, :name), {'ng-model' => 'new_distributor_id'} = f.submit 'Add distributor', 'ng-click' => 'addDistributor($event)' .actions diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 2c6aa1fcbd..c1bada0060 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -6,7 +6,7 @@ feature %q{ }, js: true do include AuthenticationWorkflow include WebHelper - + before :all do @orig_default_wait_time = Capybara.default_wait_time Capybara.default_wait_time = 5 @@ -342,4 +342,71 @@ feature %q{ OrderCycle.all.map { |oc| oc.orders_close_at.sec }.should == [1, 3, 5] end + context 'as an Enterprise user' do + + let(:supplier1) { create(:supplier_enterprise, name: 'First Supplier') } + let(:supplier2) { create(:supplier_enterprise, name: 'Another Supplier') } + let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') } + let(:distributor2) { create(:distributor_enterprise, name: 'Another Distributor') } + + before(:each) do + product = create(:product, supplier: supplier1) + product.distributors << distributor1 + product.save! + + @new_user = create_enterprise_user + @new_user.enterprise_roles.build(enterprise: supplier1).save + @new_user.enterprise_roles.build(enterprise: distributor1).save + + login_to_admin_as @new_user + end + + scenario "can view products I am coordinating" do + oc_user_coordinating = create(:simple_order_cycle, { coordinator: supplier1, name: 'Order Cycle 1' } ) + oc_for_other_user = create(:simple_order_cycle, { coordinator: supplier2, name: 'Order Cycle 2' } ) + + click_link "Order Cycles" + + page.should have_content oc_user_coordinating.name + page.should_not have_content oc_for_other_user.name + end + + scenario "can create a new order cycle" do + click_link "Order Cycles" + click_link 'New Order Cycle' + + fill_in 'order_cycle_name', with: 'My order cycle' + fill_in 'order_cycle_orders_open_at', with: '2012-11-06 06:00:00' + fill_in 'order_cycle_orders_close_at', with: '2012-11-13 17:00:00' + + select 'First Supplier', from: 'new_supplier_id' + click_button 'Add supplier' + + select 'First Distributor', from: 'order_cycle_coordinator_id' + + select 'First Distributor', from: 'new_distributor_id' + click_button 'Add distributor' + + # Should only have suppliers / distributors listed which the user can manage + within "#new_supplier_id" do + page.should_not have_content supplier2.name + end + within "#new_distributor_id" do + page.should_not have_content distributor2.name + end + within "#order_cycle_coordinator_id" do + page.should_not have_content distributor2.name + page.should_not have_content supplier1.name + page.should_not have_content supplier2.name + end + + click_button 'Create' + + flash_message.should == "Your order cycle has been created." + order_cycle = OrderCycle.find_by_name('My order cycle') + order_cycle.coordinator.should == distributor1 + end + + end + end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index b757eb744e..9007ff8a2a 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -13,22 +13,10 @@ module Spree let(:s2) { create(:supplier_enterprise) } let(:d1) { create(:distributor_enterprise) } let(:d2) { create(:distributor_enterprise) } - # create product for each enterprise + let(:p1) { create(:product, supplier: s1, distributors:[d1, d2]) } let(:p2) { create(:product, supplier: s2, distributors:[d1, d2]) } - # create order for each enterprise - let(:o1) do - o = create(:order, distributor: d1, bill_address: create(:address)) - create(:line_item, order: o, product: p1) - o - end - let(:o2) do - o = create(:order, distributor: d2, bill_address: create(:address)) - create(:line_item, order: o, product: p1) - o - end - subject { user } let(:user){ nil } @@ -55,7 +43,7 @@ module Spree should have_ability(:create, for: Spree::Product) end - it "should be able to read/write their enterprises' product variants" do + it "should be able to read/write their enterprises' product variants" do should have_ability([:admin, :index, :read, :create, :edit], for: Spree::Variant) end @@ -66,7 +54,7 @@ module Spree it "should be able to read/write their enterprises' product images" do should have_ability([:admin, :index, :read, :create, :edit], for: Spree::Image) end - + it "should be able to read Taxons (in order to create classifications)" do should have_ability([:admin, :index, :read, :search], for: Spree::Taxon) end @@ -74,6 +62,7 @@ module Spree it "should be able to read/write Classifications on a product" do should have_ability([:admin, :index, :read, :create, :edit], for: Spree::Classification) end + end context "when is a distributor enterprise user" do @@ -84,13 +73,24 @@ module Spree d1.enterprise_roles.build(user: user).save user end + # create order for each enterprise + let(:o1) do + o = create(:order, distributor: d1, bill_address: create(:address)) + create(:line_item, order: o, product: p1) + o + end + let(:o2) do + o = create(:order, distributor: d2, bill_address: create(:address)) + create(:line_item, order: o, product: p1) + o + end it "should be able to read/write their enterprises' orders" do - should have_ability([:admin, :index, :read, :edit], for: o1) + should have_ability([:admin, :index, :read, :edit], for: o1) end it "should not be able to read/write other enterprises' orders" do - should_not have_ability([:admin, :index, :read, :edit], for: o2) + should_not have_ability([:admin, :index, :read, :edit], for: o2) end it "should be able to create a new order" do @@ -114,6 +114,29 @@ module Spree end end + context 'Order Cycle co-ordinator' do + + let (:user) do + user = create(:user) + user.spree_roles = [] + s1.enterprise_roles.build(user: user).save + user + end + let(:oc1) { create(:simple_order_cycle, {coordinator: s1}) } + let(:oc2) { create(:simple_order_cycle) } + + it "should be able to read/write OrderCycles they are the co-ordinator of" do + should have_ability([:admin, :index, :read, :edit], for: oc1) + end + + it "should not be able to read/write OrderCycles they are not the co-ordinator of" do + should_not have_ability([:admin, :index, :read, :create, :edit], for: oc2) + end + + it "should be able to create OrderCycles" do + should have_ability([:create], for: OrderCycle) + end + end end end end \ No newline at end of file