From 6c4db7fc226c3766a9b4e4aebbedd0f13fd8e225 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 18 Mar 2015 17:50:12 +1100 Subject: [PATCH] Adding permission to view outgoing exchanges to producers who have granted P-OC to the relevant outgoing hub --- lib/open_food_network/permissions.rb | 27 ++++++++++++++- .../lib/open_food_network/permissions_spec.rb | 33 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/open_food_network/permissions.rb b/lib/open_food_network/permissions.rb index aa47fef16a..62e202395f 100644 --- a/lib/open_food_network/permissions.rb +++ b/lib/open_food_network/permissions.rb @@ -55,7 +55,7 @@ module OpenFoodNetwork # Find the exchanges of an order cycle that an admin can manage def order_cycle_exchanges(order_cycle) - ids = order_cycle_exchange_ids_involving_my_enterprises(order_cycle) + ids = order_cycle_exchange_ids_involving_my_enterprises(order_cycle) | order_cycle_exchange_ids_distributing_my_variants(order_cycle) Exchange.where(id: ids, order_cycle_id: order_cycle) end @@ -97,6 +97,16 @@ module OpenFoodNetwork Enterprise.where('id IN (?)', parent_ids) end + # Related enterprises receiving 'permission' FROM 'enterprises' + def related_enterprises_receiving(permission, enterprises) + child_ids = EnterpriseRelationship. + permitted_by(enterprises). + with_permission(permission). + pluck(:child_id) + + Enterprise.where('id IN (?)', child_ids) + end + def managed_enterprise_products Spree::Product.managed_by(@user) end @@ -109,5 +119,20 @@ module OpenFoodNetwork # Any exchanges that my managed enterprises are involved in directly order_cycle.exchanges.involving(managed_enterprises).pluck :id end + + def order_cycle_exchange_ids_distributing_my_variants(order_cycle) + # Any outgoing exchange where the distributor has been granted P-OC by one or more of my producers + hubs = related_enterprises_receiving(:add_to_order_cycle, managed_enterprises.is_primary_producer).is_hub.pluck(:id) + permitted_exchanges = order_cycle.exchanges.outgoing.where(receiver_id: hubs) + + # TODO: remove active_exchanges when we think it is safe to do so + # active_exchanges is for backward compatability, before we restricted variants in each + # outgoing exchange to those where the producer had granted P-OC to the distributor + # For any of my managed producers, any outgoing exchanges with their variants + variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', managed_enterprises.is_primary_producer) + active_exchanges = order_cycle.exchanges.outgoing.with_any_variant(variants).pluck :id + + permitted_exchanges | active_exchanges + end end end diff --git a/spec/lib/open_food_network/permissions_spec.rb b/spec/lib/open_food_network/permissions_spec.rb index 4c2c34a5f1..009c024a78 100644 --- a/spec/lib/open_food_network/permissions_spec.rb +++ b/spec/lib/open_food_network/permissions_spec.rb @@ -136,6 +136,39 @@ module OpenFoodNetwork permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) } permissions.order_cycle_exchanges(oc).should == [ex] end + + describe "special permissions for managers of producers" do + let!(:producer) { create(:supplier_enterprise) } + before do + ex.incoming = false + ex.save + end + + it "returns outgoing exchanges where the hub has been granted P-OC by a supplier I manage" do + permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) } + create(:enterprise_relationship, parent: producer, child: e2, permissions_list: [:add_to_order_cycle]) + + permissions.order_cycle_exchanges(oc).should == [ex] + end + + + it "does not return outgoing exchanges where only the coordinator has been granted P-OC by a producer I manage" do + permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) } + create(:enterprise_relationship, parent: producer, child: e1, permissions_list: [:add_to_order_cycle]) + + permissions.order_cycle_exchanges(oc).should == [] + end + + # TODO: this is testing legacy behaviour for backwards compatability, remove when behaviour no longer required + it "returns outgoing exchanges which include variants produced by a producer I manage" do + product = create(:product, supplier: producer) + variant = create(:variant, product: product) + ex.variants << variant + permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) } + + permissions.order_cycle_exchanges(oc).should == [ex] + end + end end describe "finding managed products" do